/// Copyright (c) 2005-2008, Simon Howard
/// Permission to use, copy, modify, and/or distribute this software
/// for any purpose with or without fee is hereby granted, provided
/// that the above copyright notice and this permission notice appear
/// in all copies.
/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
/// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
/// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
/// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
/// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
/// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

/// A hash function for a generic pointer.
/// This function takes a reference to any type and returns a hash value
/// based on the memory address of the reference.
pub fn pointer_hash<T>(location: &T) -> u32 {
    // Convert the reference to a raw pointer and then to an integer.
    let ptr_value = location as *const T as usize;
    ptr_value as u32
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_pointer_hash() {
        // Create a concrete type for testing.
        let value = 42;

        // Calculate the hash for the reference.
        let hash = pointer_hash(&value);

        // Verify that the hash is consistent for the same reference.
        assert_eq!(pointer_hash(&value), hash);

        // Create another value and ensure the hash is different.
        let another_value = 100;
        assert_ne!(pointer_hash(&another_value), hash);
    }
}
